define('apps/common/UserCard', ['core/jQuery', 'core/Geometry', 'core/ajax/Ajax', 'core/popup/HoverTip', 'core/AsyncLoader'], function(require) {
    
    var $ = require('core/jQuery'),
        Geometry = require('core/Geometry'),
        HoverTip = require('core/popup/HoverTip'),
        AsyncLoader = require('core/AsyncLoader'),
        Ajax = require('core/ajax/Ajax'),
        mix = K.mix,
        
        URL = {
            'usercard' : '/user/ajax/pagelet_card.php',
            'tracelog' : '/common/ajax/log_stat.php'
        },
        
        UserCard = K.extend(function(opts) {
            opts = opts || {
                'selector' : '._j_g_ucard',
                'shStyle' : 'fadeInOut',
                'single' : true,
                'showWait' : 500,
                'hideWait' : 300,
                'showTime' : 100,
                'hideTime' : 20
            };
            this.cardContent = {}; // 缓存card数据，防止重复请求
            UserCard.$super.call(this, opts); // 执行父类构造函数
            this.listenUserChange();
        }, HoverTip);
    
    mix(UserCard.prototype, {
        'setTip' : function(trigger) {
            var popupDom = $('<div class="usercard dn"></div>').appendTo(trigger.closest(this.context));
                    
            // 关闭事件
            popupDom.delegate('._j_close', 'click', function(ev) {
                popupDom.hide();
                ev.preventDefault();
            });
            
            // 私信初始化
            this.initMail(popupDom);

            return popupDom;
        },
        
        'initMail' : function(pop) {
            new AsyncLoader({
                'context' : pop,
                'triggerSelector' : '._j_pmail',
                'modules' : ['pic_apps/chat/ChatStartDialog'],
                'handler' : function(ChatStartDialog) {
                    new ChatStartDialog({'triggerSelector' : '._j_pmail', 'context' : pop});
                }
            });
        },
        
        'setPosition' : function(trigger, pop) {
            var posStyle = ['above', 'left'], // above-left, above-right, below-left, below-right; left-above, left-below, right-above, right-below
                targetOffset = trigger.offset(),
                viewportWidth = Geometry.viewportWidth(),
                viewportHeight = Geometry.viewportHeight(),
                targetSize = {
                    'height' : trigger.outerHeight(),
                    'width' : trigger.outerWidth()
                },
                cardSize = {
                    'height' : pop.outerHeight(),
                    'width' : pop.outerWidth()
                },
                coordinate = { // 触发用户名片的链接在当前浏览器窗口中的坐标（左上右下）
                    'left' : targetOffset.left - Geometry.scrollLeft(),
                    'top' : targetOffset.top - Geometry.scrollTop(),
                    'right' : viewportWidth + Geometry.scrollLeft() - targetOffset.left - targetSize.width,
                    'bottom' : viewportHeight + Geometry.scrollTop() - targetOffset.top - targetSize.height
                };
            
            // 判断名片应该放在触发点的什么位置
            if(coordinate.top < cardSize.height && 
               coordinate.bottom < cardSize.height &&
               viewportWidth - cardSize.width - targetSize.width >= viewportHeight - cardSize.height - targetSize.height) {
                if(coordinate.right < cardSize.width && coordinate.left >= coordinate.right) {
                    posStyle[0] = 'left';
                } else {
                    posStyle[0] = 'right';
                }
                
                if(coordinate.top < cardSize.height - targetSize.height && coordinate.bottom >= coordinate.top) {
                    posStyle[1] = 'below';
                } else {
                    posStyle[1] = 'above';
                }
            } else {
                if(coordinate.top < cardSize.height && coordinate.bottom >= coordinate.top) {
                    posStyle[0] = 'below';
                } else {
                    posStyle[0] = 'above';
                }
                
                if(coordinate.right < cardSize.width - targetSize.width && coordinate.left >= coordinate.right) {
                    posStyle[1] = 'right';
                } else {
                    posStyle[1] = 'left';
                }
            }
            pop.css(this.position(targetSize, cardSize, targetOffset, posStyle));
            
        },
        
        'position' : function(targetSize, cardSize, targetOffset, posStyle) {
            var left, top, firstP = posStyle[0], secondP = posStyle[1];

            if(firstP === 'above' || firstP === 'below') {
                if(firstP === 'above') {
                    top = targetOffset.top - cardSize.height - 5;
                } else {
                    top = targetOffset.top + targetSize.height + 5;
                }
                
                if(secondP === 'left') {
                    left = targetOffset.left;
                } else {
                    left = targetOffset.left + targetSize.width - cardSize.width;
                }
            } else {
                if(firstP === 'left') {
                    left = targetOffset.left - cardSize.width - 5;
                } else {
                    left = targetOffset.left + targetSize.width + 5;
                }
                
                if(secondP === 'above') {
                    top = targetOffset.top + targetSize.height - cardSize.height;
                } else {
                    top = targetOffset.top;
                }
            }

            return {'left':left, 'top':top};
        },
        
        'listenUserChange' : function() {
            K.on('friend:follow', $.proxy(this.removeOldCardData, this));
            K.on('friend:unfollow', $.proxy(this.removeOldCardData, this));
            K.on('friend:updatenote', $.proxy(this.removeOldCardData, this));
        },
        
        'removeOldCardData' : function(uid) {
			if(this.cardContent[uid]) {
                delete this.cardContent[uid];
            }
        },
        
        /**
         * 每次显示usercard时的属性更新操作
         */
        'deferShow' : function(trigger, tip, show) {
            var _this = this,
                uid = trigger.data('uid'),
				fromtype = trigger.data('fromtype'),
				fromdata = trigger.data('fromdata');
            
            if(!this.cardContent[uid]) {
                Ajax.get(URL.usercard+'?t='+(+new Date), {'uid' : uid , 'fromtype' : fromtype,'fromdata' : fromdata}, 
	                function(data) {
                        _this.cardContent[uid] = data;
                        tip.html(data.html);
                        _this.setPosition(trigger, tip);
                        show();
	                },
	                function(error) {
	                    K.log('Data Err:', error);
	                }
                );
            } else {
                tip.html(this.cardContent[uid].html);
                this.setPosition(trigger, tip);
                show();
            }
            
            // 记录usercard显示日志
            this.traceLog(trigger);
        },
        
        /**
         * 显示名片根据需要记录日志
         */
        'traceLog' : function(trigger) {
        	var trace = trigger.data('trace'),
        		position = trigger.data('position'),
        		params = {'type':'pic_usercard', 'position':position};
        		
        	trace && $.post(URL.tracelog, trace);
        	
        	if(trigger.data('avatarparams')) {
        		try {
        			K.mix(params, $.parseJSON(decodeURIComponent(trigger.data('avatarparams'))));
        		} catch(e) {
        			K.log('Invalid avatar params:', trigger.data('avatarparams'));
        		}
        	}
        	
        	position && K.fire('giflog', {'key':'jsstat', 'params':params, 'withUid':true});
        }
    });
    
    return UserCard;
});
